package com.db.collections;

import com.carrotsearch.sizeof.RamUsageEstimator;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * @author Alexander Kotov (kotov.alex.22@gmail.com)
 */
public class MemoryTest {
    final Runtime runtime = Runtime.getRuntime();
    final Random random = new Random();
    final private int ELEMENTS_COUNT = 10000000;
    final private Map<Integer, Integer> warmUpMap = new HashMap<Integer, Integer>();

    private void warmUpMemory() {
        for (int i = 0; i < 1000000; ++i) {
            warmUpMap.put(i, random.nextInt());
        }
    }

    private void run() throws InterruptedException {
        //IntHashMap
        System.gc();
        long memory = runtime.totalMemory() - runtime.freeMemory();
        IntHashMap intHashMap = new IntHashMap(16, 1.f);
        for (int i = 0; i < ELEMENTS_COUNT; ++i) {
            intHashMap.put(i, random.nextInt());
        }
        System.gc();
        memory = runtime.totalMemory() - runtime.freeMemory() - memory;
        System.out.println("IntHashMap: " + memory + " bytes");
        long sizeOfIntHashMap = RamUsageEstimator.sizeOf(intHashMap);
        System.out.println("size of IntHashMap: " + sizeOfIntHashMap +
                " bytes, per element: " + sizeOfIntHashMap / ELEMENTS_COUNT);
        System.out.println("--------------------------------");
        System.out.println(intHashMap.size());
        System.out.println("================================");

        //IntHashMap2
        System.gc();
        memory = runtime.totalMemory() - runtime.freeMemory();
        IntHashMap2 intHashMap2 = new IntHashMap2(16, 1.f);
        for (int i = 0; i < ELEMENTS_COUNT; ++i) {
            intHashMap2.put(i, random.nextInt());
        }
        System.gc();
        memory = runtime.totalMemory() - runtime.freeMemory() - memory;
        System.out.println("IntHashMap2: " + memory + " bytes");
        long sizeOfIntHashMap2 = RamUsageEstimator.sizeOf(intHashMap2);
        System.out.println("size of IntHashMap2: " + sizeOfIntHashMap2 +
                           " bytes, per element: " + sizeOfIntHashMap2 / ELEMENTS_COUNT);
        System.out.println("--------------------------------");
        System.out.println(intHashMap2.size());
        System.out.println("================================");

        //HashMap
        System.gc();
        memory = runtime.totalMemory() - runtime.freeMemory();
        HashMap<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
        for (int i = 0; i < ELEMENTS_COUNT; ++i) {
            hashMap.put(i, random.nextInt());
        }
        System.gc();
        memory = runtime.totalMemory() - runtime.freeMemory() - memory;
        System.out.println("HashMap: " + memory + " bytes");
        long sizeOfHashMap = RamUsageEstimator.sizeOf(hashMap);
        System.out.println("size of HashMap: " + sizeOfHashMap +
                " bytes, per element: " + sizeOfHashMap / ELEMENTS_COUNT);
        System.out.println("--------------------------------");
        System.out.println(hashMap.size());
        System.out.println("================================");
        System.out.println(warmUpMap.hashCode());

    }

    public static void main(String[] args) throws InterruptedException {
        MemoryTest memoryTest = new MemoryTest();
        memoryTest.warmUpMemory();
        memoryTest.run();
    }
}
